A typical computer system includes at least a microprocessor and some form of memory. The microprocessor has, among other components, arithmetic, logic, and control circuitry that interpret and execute instructions necessary for the operation and use of the computer system. FIG. 1 shows a typical computer system 10 having a microprocessor 12, memory 14, integrated circuits 16 that have various functionalities, and communication paths 18, i.e., buses and signals, that are necessary for the transfer of data among the aforementioned components of the computer system 10.
Microprocessors, and other types of integrated circuits, have a large number of functional units to enable them to execute multiple instructions in parallel. Although such microprocessors are capable of executing many instructions in a given clock cycle, the average number of instructions executed per clock cycle is typically slightly above 1. One reason for this stems from the chains of dependencies between instructions, i.e., where a given instruction is dependent on one or more older instructions. In other words, because execution of one instruction, in many cases, depends on execution of one or more other instructions, peak parallelism, and hence, peak performance, is difficult to attain on a constant basis.
One of the undesired effects of such parallelism inefficiency is high, and wasted, power consumption. Because a functional unit continues to operate, i.e., get clocked, irrespective of whether all or a portion of the functional unit is being used, power is wasted. In response, designers, in order to reduce average power consumption, have devised techniques to enable a microprocessor to determine which functional units are not being used and disable the clocks to them. By disabling the clock to a functional unit, state devices, which are major sources of power consumption, cannot switch state, and therefore, cannot partake in unnecessary and wasted power consumption.
FIG. 2 shows a typical implementation of an instruction decode/issue unit 20 and a plurality of functional units 1 . . . n 22, 24, and 26. The instruction decode/issue unit 20 processes an incoming stream of instructions 27 and selectively dispatches them to functional units 1 . . . n 22, 24, and 26 via instruction signals 42, 44, and 46, respectively. AND gates 30, 32, and 34 each input a clock signal, CLK 28, and a unit enable signal (unit_enable_136 for functional unit 22, unit_enable_238 for functional unit 24, and unit_enable_n 40 for functional unit n). If the unit enable signal, under control of the instruction decode/issue unit 20, is ‘low,’ the corresponding AND gate outputs ‘low’ to the respective functional unit. Alternatively, when the instruction decode/issue unit 20 outputs ‘high’ on a particular unit enable signal, then the corresponding AND gate outputs the clock signal 28 to the respective functional unit. Thus, when the unit enable signal to a particular functional unit is ‘high,’ that functional unit remains ‘on’ because the clock signal 28 is allowed to clock the components of that functional unit. In other words, when the unit enable signal to a functional unit is ‘high,’ the clock signal 28 to that functional unit is allowed to clock state devices in the functional unit so that such state devices can switch, i.e., update their state.
The unit enable signals from the instruction decode/issue unit 20 to the functional units 1 . . . n 22, 24, and 26 facilitate power saving when one or more functional units do not need to be clocked during one or more clock cycles. For example, if upon decoding, the instruction decode/issue unit 20 determines that a particular functional unit will not be needed in the current or a future clock cycle, the instruction decode/issue unit 20 may disable that functional unit, via the corresponding unit enable signal, at the appropriate time in order to save power.
However, although power may be saved using such an implementation as shown in FIG. 2, freezing the state of certain functional unit while allowing other functional units to be clocked has the undesirable side effect of introducing bugs, i.e., operational state inconsistencies. By holding state in some functional units and updating state in other functional units, the total number of possible states in an integrated circuit design may increase exponentially. Hence, the likelihood of bugs increases the complexity of verification and resources needed to find and fix such bugs. In fact, bugs which take a large amount of time (in terms of clock cycles) to manifest themselves can often be virtually impossible to find before actual fabrication of the integrated circuit. Moreover, even in a post-fabrication stage, verification, in many cases, is prohibitively expensive from both a monetary and time perspective.